﻿using EONFULLSIN2.Core;
using EONFULLSIN2.Core.Extensions;
using EONFULLSIN2.Core.Utils;
using EONFULLSIN2.Models.Attributes;
using EONFULLSIN2.Models.Dto.Device;
using EONFULLSIN2.Models.Enum.SensorPoint;
using EONFULLSIN2.Services.Device.JuYing;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EONFULLSIN2.Services.Device.ZhongChuangZhiHe {

    public class ZczhModbusService : ModbusBaseServices, IZczhModbusService {

        private static byte slaveId = 1;// Modbus 从站 ID，通常为 1
        private static ushort startAddress = 0;// 从哪个寄存器地址开始读取
        private static ushort numRegisters = 24;// 要读取的寄存器数量（例如，读取 24 个寄存器）

        public override string IpAddress { protected set; get; } = "192.168.1.7";

        public override int Port { protected set; get; } = 20108;

        /// <summary>
        /// 电流枚举列表
        /// </summary>
        public List<eCurrentPointEnum?> CurrentPointEnums => Enum.GetValues(typeof(eCurrentPointEnum)).Cast<eCurrentPointEnum?>().ToList();
        /// <summary>
        /// 电压枚举列表
        /// </summary>
        public List<eVoltagePointEnum?> VoltagePointEnums => Enum.GetValues(typeof(eVoltagePointEnum)).Cast<eVoltagePointEnum?>().ToList();


        public async Task<List<SensorItemDto>> GetSensorDataAsync() {
            if (IsConnect) {
                //Convert.ToByte(24)

                List<SensorItemDto> sensorItemDtos = new List<SensorItemDto>();
                // 1.发送查询指令 01 03 00 00 00 18 45 C0
                var read = _tcpClient.Client.Send(new byte[] { 0x01, 0x03, 0x00, 0x00, 0x00, 0x18, 0x45, 0xC0 });
                // 2.接收数据
                byte[] readData = new byte[1024];
                await _tcpClient.Client.ReceiveAsync(readData);
                // 3.提取数据区（跳过前3字节：从站地址+功能码+数据长度；跳过最后2字节CRC）中间48字节为有效数据
                var startDataIndex = readData[1];
                var endDataIndex = readData[2];
                var dataArea = readData.Skip(startDataIndex).Take(endDataIndex).ToArray();

                // 4.拆分24组数据（每组2字节，高字节在前），计算原始值（0 - 10000）
                ushort[] rawValues = new ushort[endDataIndex / 2];
                for (int i = 0; i < 24; i++) {
                    int byteIndex = i * 2; // 每组占2字节，计算起始索引
                    byte highByte = dataArea[byteIndex]; // 高字节（前8位）
                    byte lowByte = dataArea[byteIndex + 1]; // 低字节（后8位）
                    rawValues[i] = (ushort)((highByte << 8) | lowByte); // 组合为16位无符号整数
                }

                if (rawValues != null && rawValues.Length > 0) {
                    for (int i = 0; i < rawValues.Length; i++) {
                        SensorItemDto sensorItemDto = new SensorItemDto();
                        sensorItemDto.ID = i;
                        sensorItemDto.DataSourceAddress = i;
                        double readValue = 0;
                        SensorPointAttribute sensorPointAttribute = default;
                        //前12个为电流
                        if (i <= 11) {
                            sensorItemDto.Type = Models.Enum.eSensorTypeEnum.Current;
                            readValue = Math.Round(rawValues[i] * 5.0 / 10000 * 4, 3);//前4个为压缩机电流，乘以4倍

                            var currentPointEnum = CurrentPointEnums.FirstOrDefault(o => o.GetAttributeOfType<SensorPointAttribute>().ChannelIndex == i);
                            sensorPointAttribute = currentPointEnum?.GetAttributeOfType<SensorPointAttribute>();

                        } else if (i > 11) {//后12个为电压
                            sensorItemDto.Type = Models.Enum.eSensorTypeEnum.Voltage;
                            readValue = Math.Round(rawValues[i] * 250.0 / 10000, 2);

                            var voltagePointEnum = VoltagePointEnums.FirstOrDefault(o => o.GetAttributeOfType<SensorPointAttribute>().ChannelIndex == i);
                            sensorPointAttribute = voltagePointEnum?.GetAttributeOfType<SensorPointAttribute>();
                        }
                        sensorItemDto.CodeNumber = sensorPointAttribute?.ChannelName ?? "-";
                        sensorItemDto.Description = sensorPointAttribute?.Description ?? "-";
                        sensorItemDto.Name = sensorPointAttribute?.Name ?? "-";
                        sensorItemDto.Value = readValue;
                        sensorItemDtos.Add(sensorItemDto);
                    }

                } else {
                    LogManager.Error($"未读取到寄存器数据，startIndex：{startAddress}，readCount：{numRegisters}");
                }
                return sensorItemDtos;
            }
            throw new Exception($"{IpAddress}:{Port},is not connect");
        }


        public async Task<double?> GetCurrentDataByIndexAsync(eCurrentPointEnum eCurrentPointEnum) {
            var list = await GetSensorDataAsync();
            var item = list?.FirstOrDefault(o => o.CodeNumber == eCurrentPointEnum.GetAttributeOfType<SensorPointAttribute>()?.ChannelName);
            return item is null ? null : Convert.ToDouble(item.Value);
        }

        public async Task<double?> GetVoltageDataByIndexAsync(eVoltagePointEnum eVoltagePointEnum) {
            var list = await GetSensorDataAsync();
            var item = list?.FirstOrDefault(o => o.CodeNumber == eVoltagePointEnum.GetAttributeOfType<SensorPointAttribute>()?.ChannelName);
            return item is null ? null : Convert.ToDouble(item.Value);
        }
    }

}
